// node 服务器，处理浏览器加载的各种请求
const Koa = require("koa");
const fs = require("fs");
const path = require("path");
const compilerSFC = require("@vue/compiler-sfc");
const compilerDOM = require("@vue/compiler-dom");
const app = new Koa();

app.use(async (ctx) => {
  const { url, query } = ctx;
  // 处理主页
  if (url === "/") {
    ctx.type = "text/html";
    ctx.body = fs.readFileSync(path.join(__dirname, "index.html"), "utf8");
  } else if (url.endsWith(".js")) {
    // 解决 js 文件的请求
    const p = path.join(__dirname, url);
    ctx.type = "application/javascript";
    ctx.body = rewriteImport(fs.readFileSync(p, "utf8"));
  } else if (url.startsWith("/@modules/")) {
    const moduleName = url.replace("/@modules/", "");
    const prefix = path.join(__dirname, "node_modules", moduleName);
    const modulePath = require(prefix + "/package.json").module;
    const filePath = path.join(prefix, modulePath);
    const result = fs.readFileSync(filePath, "utf8");
    ctx.type = "application/javascript";
    ctx.body = rewriteImport(result);
  } else if (url.indexOf(".vue") > -1) {
    const p = path.join(__dirname + url.split("?")[0]);
    const result = compilerSFC.parse(fs.readFileSync(p, "utf-8"));
    if (!query.type) {
      // SFC 单文件组件
      const scriptContent = result.descriptor.script.content;
      const script = scriptContent.replace(
        "export default",
        "const __script = "
      );
      ctx.type = "application/javascript";
      ctx.body = `
        ${rewriteImport(script)}
        // 解析 template
        import { render as __render } from '${url}?type=template'
        __script.render = __render
        export default __script
      `;
    } else if (query.type === "template") {
      // template 单独处理
      const templateContent = result.descriptor.template.content;
      const templateModule = compilerDOM.compile(templateContent, {
        mode: "module",
      });
      const render = templateModule.code;
      ctx.type = "application/javascript";
      ctx.body = rewriteImport(render);
    }
  }
});

function rewriteImport(content) {
  return content.replace(/ from ['"](.*)['"]/g, function (s1, s2) {
    if (s2.startsWith("./") || s2.startsWith("../") || s2.startsWith("/")) {
      return s1;
    } else {
      return ` from '/@modules/${s2}'`;
    }
  });
}

app.listen(3000, () => {
  console.log(`listen 3000`);
});
